iT邦幫忙

2024 iThome 鐵人賽

DAY 15
1
Python

使用 WiFiBoy Python 玩學機來學物聯網應用 系列 第 15

15. 控制 LCD1602 液晶顯示器

  • 分享至 

  • xImage
  •  

LCD1602 模組介紹

LCD1602 是一款常見的文字數字型液晶顯示模組,通常用來顯示簡短文字訊息。具有 16 行 2 列的顯示區域,最多同時可以顯示 32 個文字。

規格

  • 顯示範圍: 16 行 X 2 列
  • 字體大小: 5 x 8 像素點
  • 傳輸介面: 16 針腳位,有 8條數據線與幾條控制線。
  • 工作電壓: 4.7 ~ 5.3V
  • 背光: 黃色或藍色,可獨立控制
  • 對比度調整: 可透過外部旋鈕進行對比度調整。

我們過去在玩 Arduino 學習版時,常會買 I2C 通訊介面的 LCD1602 模組,這樣與其他元件整合時,就不會整個麵包版都插滿線。

I2C 傳輸協定簡介

I2C(Inter-Integrated Circuit),中文叫集成电路总线,它是一种串行通信总线,使用多主从架构,是由飞利浦公司在1980年代初设计的,方便了主板、嵌入式系统或手机与周边设备组件之间的通讯。由于其简单性,它被广泛用于微控制器与传感器阵列,显示器,IoT设备,EEPROM等之间的通信。

最重要的功能包括:

只需要两条总线
所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址
I2C是真正的多主设备总线,可提供仲裁和冲突检测
传输速度
标准模式:Standard Mode = 100 Kbps
快速模式:Fast Mode = 400 Kbps
高速模式: High speed mode = 3.4 Mbps
超快速模式: Ultra fast mode = 5 Mbps
最大主设备数:无限制
最大从机数:理论上是127
大白话:一种只用2根线就可以传递很多数据给其它多台设备的方法,这种方法叫I2C

大大减少了MCU上IO的使用

MicroPython LCD1602 驅動程式簡介

MicroPython 官網上有對於 I2C 傳輸的介紹資料 Software I2C Bus

程式碼

掃描 I2C 傳輸介面的位址

# I2C 掃描程式
import machine
I2C_SDA_PIN = 23
I2C_SCL_PIN = 22
i2c=machine.I2C(0,sda=machine.Pin(I2C_SDA_PIN), scl=machine.Pin(I2C_SCL_PIN), freq=400000)
print('Scanning I2C bus.')
devices = i2c.scan() # this returns a list of devices
device_count = len(devices)
if device_count == 0:
    print('No i2c device found.')
else:
    print(device_count, 'devices found.')
for device in devices:
    print('Decimal address:', device, ", Hex address: ", hex(device))

執行結果

MPY: soft reboot
Scanning I2C bus.
2 devices found.
Decimal address: 25 , Hex address:  0x19
Decimal address: 39 , Hex address:  0x27

顯示指定字串

from machine import I2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd

I2C_ADDR     = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16

i2c = I2C(0, sda=machine.Pin(23), scl=machine.Pin(22), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)    
lcd.putstr("Hi, WiFiBoy!")

做一個小時鐘

# LCD1602小時鐘
import utime
import machine
from machine import I2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd

I2C_ADDR     = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16

def test_main():
    #Test function for verifying basic functionality
    print("Running test_main")
    i2c = I2C(0, sda=machine.Pin(23), scl=machine.Pin(22), freq=400000)
    lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)    
    count = 0
    lcd.backlight_on()
    while True:
        lcd.clear()
        time = utime.localtime()
        lcd.putstr("{year:>04d}/{month:>02d}/{day:>02d} {HH:>02d}:{MM:>02d}:{SS:>02d}".format(year=time[0], month=time[1], day=time[2], HH=time[3], MM=time[4], SS=time[5]))
        utime.sleep(1)
        count += 1

test_main()

印出 LCD1602 可以顯示的字符

LCD1602 可以顯示的字符集是基於 ASCII 編碼與自行定義的字符。

  • 標準 ASCII: 0x20 (32) 至 0x7F (127)
  • 自行定義符號: 0x00 (0) 至 0x07 (7)
import utime
from machine import I2C, Pin
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd

I2C_ADDR     = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16

def test_main():
    # Test function for verifying LCD1602 full character set
    print("Running LCD1602 full character set")
    
    # 初始化 I2C
    i2c = I2C(0, sda=Pin(23), scl=Pin(22), freq=400000)
    lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
    
    lcd.backlight_on()
    lcd.clear()
    
    # LCD1602 支援的符號
    lcd_chars = []
    
    # 增加自己定義的符號 (0x00 至 0x07)
    for x in range(0x00, 0x08):
        lcd_chars.append(chr(x))
    
    # 增加標準 ASCII 符號(0x20 至 0x7F)
    for x in range(0x20, 0x80):
        lcd_chars.append(chr(x))
    
    char_string = ''.join(lcd_chars)
    print("Displaying all supported characters.")
    
    # 依次顯示字符
    for i in range(0, len(char_string), I2C_NUM_COLS):
        lcd.clear()
        lcd.putstr(char_string[i:i + I2C_NUM_COLS])
        time.sleep(1)  # 每秒更新一次

# 執行程式
test_main()

如何自行定義字符?

import utime
import machine
from machine import I2C
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd

I2C_ADDR = 0x27
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16

def write_custom_char(lcd, location, char_map):
    location &= 0x07
    lcd.hal_write_command(0x40 | (location << 3))

    for line in char_map:
        lcd.hal_write_data(line)

def custom_char_demo():
    custom_chars = [
        [0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000],  # Heart
        [0b00000, 0b01010, 0b00000, 0b00000, 0b10001, 0b01110, 0b00000, 0b00000],  # Smiley
        [0b00100, 0b01110, 0b11111, 0b00100, 0b00100, 0b00100, 0b00100, 0b00000],  # Arrow Up
        [0b00100, 0b00100, 0b00100, 0b00100, 0b11111, 0b01110, 0b00100, 0b00000],  # Arrow Down
        [0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000],  # Block
        [0b00000, 0b11111, 0b10101, 0b10101, 0b11111, 0b00000, 0b00000, 0b00000],  # Checkerboard
        [0b00000, 0b11111, 0b10001, 0b10001, 0b11111, 0b00000, 0b00000, 0b00000],  # Frame
        [0b00000, 0b00000, 0b00100, 0b01110, 0b00100, 0b00000, 0b00000, 0b00000]   # Dot
    ]

    i2c = I2C(0, sda=machine.Pin(23), scl=machine.Pin(22), freq=400000)
    lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)

    for i in range(8):
        write_custom_char(lcd, i, custom_chars[i])

    lcd.clear()
    lcd.putstr("Custom Chars:\n")
    for i in range(8):
        lcd.putstr(chr(i))
    utime.sleep(10)

custom_char_demo()

參考資料

  1. coderdojotc.org_10-character-lcd-display
  2. LCD 1602 驅動程式

上一篇
14. 連接 MAX7219 LED 矩陣顯示模組
下一篇
16. 顯示 QR CODE
系列文
使用 WiFiBoy Python 玩學機來學物聯網應用 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言